package com.zhw.task;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 使用邻接表来表示有向无环图
 * 一个任务执行的前提是它在map中没有以它作为key的entry，或者是它的前置任务集合中的任务都是已执行的状态
 */
public class Digraph {

    /**
     * 顶点集合，也就是任务集合
     */
    private Set<Task> tasks;

    /**
     * 任务依赖关系集合
     * key是一个任务，value是它的前置任务集合
     */
    private Map<Task, Set<Task>> map;

    public Digraph() {
        this.tasks = new HashSet<>();
        this.map = new HashMap<>();
    }

    /**
     * 添加边的前提条件是顶点已存在
     * @param task 任务
     * @param prev 前置依赖任务
     */
    public void addEdge(Task task, Task prev) {
        if (!tasks.contains(task) || !tasks.contains(prev)) {
            throw new IllegalArgumentException();
        }
        Set<Task> prevs = map.computeIfAbsent(task, k -> new HashSet<>());
        if (prevs.contains(prev)) {
            throw new IllegalArgumentException();
        }
        prevs.add(prev);
    }

    public void addTask(Task task) {
        if (tasks.contains(task)) {
            throw new IllegalArgumentException();
        }
        tasks.add(task);
    }

    public void remove(Task task) {
        if (!tasks.contains(task)) {
            return;
        }
        map.remove(task);
        for (Set<Task> set : map.values()) {
            set.remove(task);
        }
    }

    public Set<Task> getTasks() {
        return tasks;
    }

    public void setTasks(Set<Task> tasks) {
        this.tasks = tasks;
    }

    public Map<Task, Set<Task>> getMap() {
        return map;
    }

    public void setMap(Map<Task, Set<Task>> map) {
        this.map = map;
    }

}
